package com.anthill.events.hosts
{
import com.anthill.controllers.EventBus;
import com.anthill.events.AnthillEvent;

import flash.events.Event;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;

import mx.utils.ObjectUtil;


[DefaultProperty("children")]
/**
 *  Dispatcher contain anthill events and 
 *  provide method to dispatch them.
 * 
 */ 
public class Dispatcher extends EventBus
{
	include "../../Version.as";
	
	/**
     *  Constructor. 
     *  
     */  
	public function Dispatcher()
	{
	}
		
	/**
     *  @private
     *  Storage for children property.
     */
    private var _children:Array = [];
    
    [Inspectable(category="General", arrayType="com.anthill.events.AnthillEvent")]
    [Bindable("childrenChanged")]
	 /**
     *  Array of anthill events.
     *
     *  @default false
     */ 	
    public function get children():Array
    {
        return _children;
    }
    
    [ArrayElementType("com.anthill.events.AnthillEvent")] 
    /**
     *  @private
     */
    public function set children(value:Array):void
    {
		_children = value;
		for each (var event:AnthillEvent in _children)
		{
			event.parent = this;	
		}
		dispatchEvent(new Event("childrenChanged"));
	}
	
	/**
     *  @private
     */	
	override public function dispatchEvent(event:Event) : Boolean
	{
		if(!(event is AnthillEvent))
			return super.dispatchEvent(event);
		
		// anrhill event should have eventType
		if((event as AnthillEvent).eventType == "")
			throw(new Error("eventType can't be blank."));
		
		//clone event and dispath
		var cls:Class = getDefinitionByName(getQualifiedClassName(event)) as Class;
		var e:Event = new cls((event as AnthillEvent).eventType );
		var o:Object = ObjectUtil.getClassInfo(event);
		for each(var p:QName in o.properties)
		{
			// property can be read-only
			try{
				// skip updating standard properties 
				if(p.localName != "handler" && p.localName != "bindable" && 
				   p.localName != "dispatcher" &&  p.localName != "eventType" &&
				   p.localName != "trigger" &&  p.localName != "triggerEvent")
				e[p.localName] = event[p.localName];
			}catch(e:Error){}
		}
		return super.dispatchEvent(e);
	}
}
}